package io.traveller.apiGateway.server.filter.pre;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import io.traveller.apiGateway.client.constants.SecurityLevel;
import io.traveller.apiGateway.server.context.RequestContextHelper;
import io.traveller.apiGateway.server.filter.FilterType;
import io.traveller.auth.api.constants.AccountType;
import io.traveller.auth.api.service.AuthService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
 * 授权Filter.
 * 根据不同的安全级别，做不同的处理
 *  1. {@link SecurityLevel#NONE}, 不做任何处理
 *  2. {@link SecurityLevel#USER_LOGIN}, 校验是否登陆
 *  3. {@link SecurityLevel#AUTH}, 校验url权限
 *
 * Created by yunai on 16/9/6.
 */
public class PreAuthFilter extends ZuulFilter {

    private final Logger logger = LoggerFactory.getLogger(PreAuthFilter.class);

    private final AuthService authService;

    public PreAuthFilter(AuthService authService) {
        this.authService = authService;
    }

    @Override
    public String filterType() {
        return FilterType.PRE;
    }

    @Override
    public int filterOrder() {
        return 300;
    }

    @Override
    public boolean shouldFilter() {
        // 依赖PreGetRouteExtFilter解析的securityLevel
        RequestContext ctx = RequestContext.getCurrentContext();
        final SecurityLevel securityLevel = RequestContextHelper.getSecurityLevel(ctx);
        return securityLevel != null
                && SecurityLevel.NONE != securityLevel;
    }

    @Override
    public Object run() {
        // 校验securityLevel正确性
        RequestContext ctx = RequestContext.getCurrentContext();
        final SecurityLevel securityLevel = RequestContextHelper.getSecurityLevel(ctx);
        Assert.isTrue(SecurityLevel.USER_LOGIN.equals(securityLevel) || SecurityLevel.AUTH.equals(securityLevel),
                String.format("securityLevel值不正确, 目前的值为: %s.", securityLevel));
        final Integer serviceSys = RequestContextHelper.getServiceSys(ctx);
        Assert.notNull(serviceSys, "serviceSys不能为空.");
        final String requestURI = RequestContextHelper.getRequestURI(ctx);
        Assert.isTrue(StringUtils.hasText(requestURI), "requestURI不能为空.");
        // 校验是否登陆
        final Long accountId = RequestContextHelper.getAccountId(ctx);
        if (accountId == null) {
            RequestContextHelper.setResponse(ctx, 2, "您暂时未登陆，请进行登陆.");
            return false;
        }
        final Integer accountType = RequestContextHelper.getAccountType(ctx);
        if (!AccountType.USER.equals(accountType)) {
            RequestContextHelper.setResponse(ctx, 2, "您暂时未登陆，请进行登陆.");
            return false;
        }
        // 若权限级别为Auth，检验url权限
        if (SecurityLevel.AUTH == securityLevel) {
            boolean hasPermission = authService.hasPermission(accountId, accountType, serviceSys, requestURI,
                    RequestContextHelper.getRequestMethod(ctx));
            if (!hasPermission) {
                RequestContextHelper.setResponse(ctx, 3, "您无访问权限.");
                return false;
            }
        }
        return true;
    }

}